(1)res.write + res.end
http.createServer(function (req, res) {
if(results[0])[
res.write("<html>")
res.write("<head>")
//...
res.write("</html>")
res.end();
}
現在都直接用res.render("index.ejs",{})輸出網頁
(2)res.send = res.write + res.end
後來大家都直接用 send
app.get("/", function (req, res) {
res.send("OK, Home page....");
})
(1)
npm install
npm start (nodemon app.js)
(2)Update
當使用者點擊編輯:資料放在編輯頁面上SPA(沒有另跳頁面)
特性:使用JS編輯(rel="modal:open"),server只給值
(3)HTML
<!-- modal:open 另跳視窗開啟 -->
<a href="#ex1" rel="modal:open">
<button onclick="Edit(<%= item.id%>)">編輯</button></a>
<button onclick="Delete(<%= item.id%>)">刪除</button>
(4)index.ejs > 取值
function Edit(id) {
$.ajax({
url: "/detail/"+id,
type: "GET",
success: function(res) {
var res = JSON.parse(res)
//res.data 指 success.data
//將值傳遞進input裏頭
$("input[name='id']").val(res.data.id)
$("input[name='name']").val(res.data.name)
$("input[name='phone']").val(res.data.phone)
$("input[name='address']").val(res.data.address)
$("input[name='adult_mask']").val(res.data.adult_mask)
$("input[name='child_mask']").val(res.data.child_mask)
},
error: function() {
alert("系統錯誤!")
},
})
}
(5)index.js > SQL語法
1.取值顯示在編輯頁面上,2.頁面回傳Success or Error
index.get('/detail/:id([0-9]+)', function(req, res){
var sql = `SELECT * FROM inventory WHERE id = ?;`
var data = [req.params.id]
// exec MySQL的引用
db.exec(sql, data, function(results, fields) {
if(results[0]){ //第0筆資料
res.end(
JSON.stringify(new Success(results[0]))
)
} else {
res.end(
JSON.stringify(new Error('no result'))
)
}
})
})
(6)response.js > Success or Error輸出data(此處)或message
class Success {
constructor(data, message) {
if(typeof data === 'string') {
this.message = data
data = null
message = null
}
if(data) {
this.data = data
}
if(message) {
this.message = message
}
this.errno = 1
}
}
(7)編輯送出
$('#submit').on('click', function() {
//整理表單資料到變數
var data = $('#form').serializeArray()
//form表單內資料轉成陣列
JSONData = serializeToJSON(data)
//用post方法丟json格式的data到 /update
//陣列資料轉Json物件 ajax才能使用
$.ajax({
url: "/update", //index.js > exec方法輸出
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSONData,
success: function(res) {
var res = JSON.parse(res)
if(res.errno === 1) {
alert(res.message +"更新成功!")
location.reload()
} else if(res.errno === 0) {
alert("更新失敗!")
}
},
error: function() {
alert("系統錯誤!")
}
})
})
(8)response.js > Success or Error輸出data或message(此處)
class Success {
constructor(data, message) {
if(typeof data === 'string') {
this.message = data
data = null
message = null
}
if(data) {
this.data = data
}
if(message) {
this.message = message
}
this.errno = 1
}
}
(1)HTML
<!-- modal:open 另跳視窗開啟 -->
<a href="#ex1" rel="modal:open">
<button onclick="Edit(<%= item.id%>)">編輯</button></a>
<button onclick="Delete(<%= item.id%>)">刪除</button>
(2)index.ejs
function Delete(id) {
var JSONData = {"id": id}
JSONData = JSON.stringify(JSONData)
$.ajax({
url: "/delete",
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSONData,
success: function(res) {
var res = JSON.parse(res)
if(res.errno === 1) {
alert("刪除成功!")
location.reload()
} else if(res.errno === 0) {
alert("刪除失敗!")
}
},
error: function() {
alert("系統錯誤!")
}
})
}
(3) index.js > exec方法輸出
index.post('/delete', function(req, res){
var body = req.body
var sql = `DELETE FROM inventory WHERE id = ?;`
var data = [parseInt(body.id)] //轉數值
db.exec(sql, data, function(results, fields) {
//使用affectedRows,判斷是否有被刪除
if(results.affectedRows){
res.end(
JSON.stringify(new Success('delete success'))
)
} else {
res.end(
JSON.stringify(new Error('delete failed'))
)
}
})
})
(3)response.js > Success or Error輸出data或message(此處)
class Success {
constructor(data, message) {
if(typeof data === 'string') {
this.message = data
data = null
message = null
}
if(data) {
this.data = data
}
if(message) {
this.message = message
}
this.errno = 1
}
}
(1)promise使用then的方法
(2)promise解決Callback Hell
bludbird套件使用promise解決Callback Hell(就不會曹套)
(3)promise物件
function longTimeWork(workFine = true, errorMessage = "test") {
return new Promise( (resolve, reject) => { // 3.取得承諾物件
setTimeout( () => {
(workFine) ? resolve(200) : reject(errorMessage);
}, 1000);
})
}
(4)async + await (promise才有await)
成功//200
失敗//test02
async function usingLongTimeWork() {
try {
var result = await longTimeWork(workFine, "test02");
console.log(result);
}
catch (e) {
console.log(e); //"test"
}
}
await用處:等待時間,計算倉庫剩幾張票,再繼續賣剩下的票
避免同時多人同時購票,且電腦有時間計算票數
(1)取得承諾物件
function longTimeWork(workFine = true, errorMessage = "test") {
return new Promise( (resolve, reject) => { //
setTimeout( () => {
(workFine) ? resolve(200) : reject(errorMessage); // 5.收到,跑程式
}, 1000); //1000 = 1秒
})
}
(1-2)非同步 async + await
async function main2() {
var p = await longTimeWork(true, "test"); // 2.呼叫function ; await
console.log(p); //200
}
main2()
(1-3)想要有 成功 與 失敗 的輸出分類時
function usingLongTimeWork() {
longTimeWork(true, "test") // try true/false
.then(function (e) { // 成功時:resolve(200) ; e變數
console.log('ok2yoyo'+ e); //ok2yoyo200
})
.catch(function (e) { // 失敗時:reject(errorMessage)
console.log('ok3'+ e);
})
}
(2)02_AsyncAwait:(1)的綜合簡寫 + =>函式
Promise + await (無須then 已内建)
function longTimeWork(workFine = true, errorMessage = "test") {
return new Promise( (resolve, reject) => { //取得承諾物件
setTimeout( () => {
(workFine) ? resolve(200) : reject(errorMessage);
}, 1000);
})
}
//想要有 成功 與 失敗 的輸出分類時
async function usingLongTimeWork() {
try {
//longTimeWork( true / false , "test")
var result = await longTimeWork(false, "test");
console.log(result);
}
catch (e) {
console.log(e); //"test"
}
console.log("123")
}
usingLongTimeWork();
(3)03_testOnHtml (Promise + await)
function longTimeWork(workFine = true, errorMessage = "test") {
return new Promise((resolve, reject) => {
setTimeout(() => {
workFine ? resolve(200) : reject(errorMessage);
}, 5000);
});
}
async function usingLongTimeWork(isOK) {
try {
var result = await longTimeWork(isOK, "test");
console.log(result);
} catch (e) {
console.log(e);
}
}
console.log("flag A");
usingLongTimeWork(true); //200(五秒後出現)
console.log("flag B");
usingLongTimeWork(false); //test(五秒後出現)
console.log("flag C");
(4)非同步 async + await(總共用5秒)
async function living() {
var total = 0;
var result1 = await happy(200, 2000);
// result1 跑完才往下執行
console.log(result1);
var result2 = await sad(-100, 3000);
// 等result1跑完 result2 才執行
console.log(result2);
total = result1 + result2;
console.log("total:", total);
}
(5)同步進行 async + 變數 + await(總共用3秒)
async function living() {
var promise1 = happy(200, 2000);
var promise2 = sad(-100, 3000);
var result1 = await promise1;
var result2 = await promise2;
//同時進行,但等待完才將答案送到結果,所以只花3秒鐘
var total = result1 + result2;
console.log("total:", total);
}
(6)5進化版[,]
async function living() {
var promise1 = happy(200, 2000);
var promise2 = sad(-100, 3000);
let [result1, result2] =
await Promise.all([promise1, promise2]); //需要同步進行時,塞在同一的陣列
var total = result1 + result2;
console.log("total:", total);
}
(7)更偷懶 直接塞方法(省略倉庫)
async function living() {
let [result1, result2] =
await Promise.all([happy(200, 2000), sad(-100, 3000)]); //省略倉庫
var total = result1 + result2;
console.log("total:", total);
}
舉例:1個商品有3個人同時購買
但剛好在同一秒鐘,三個人同時點下購入,會變成3個人都交易成功
為了避免,就要使用這個方法
(1)Demo_Multi_Users(SQL_Server)
顧客買商品各一個:Demo_Multi_Users(SQL_Server) > ClientA、B、C.sql
此時會導致資料庫誤讀,因為同時購買
select @count = UnitsInStock from Products where ProductID = 1
waitfor delay '00:00:15' //同時間00:00:15購買
update Products set UnitsInStock = @count - 1 where ProductID = 1
老師用sql server,但MySQL應該也可以使用
(2)新增資料庫 MySQL
create database ticketdb default character set utf8;
use ticketdb;
create table concert
(
concertId int auto_increment not null primary key,
concertName varchar(30),
count int
);
insert into concert (concertName, count) values
('Jody''s last conert', 1000),
('Jeter say good-bye', 2000);
select * from concert;
(3) > npm start
"scripts": {
"start": "nodemon ./bin/www"
},
(4) ticket.js (await + FOR UPDATE)
await req.mysql.queryAsync("start transaction", []);
//交易機制SQL備份,之後rollback恢復(大家同時搶票,同時交易會同時產生訂單(錯誤),系統出錯rollback恢復,再搶一次)
var data = await req.mysql.queryAsync("select * from concert where concertId = 1 for update", []);
// FOR UPDATE 鎖資料鎖到交易完成
// 多人鎖定控制 更改 (票只剩一張,只能看不能下單)
// 為了確定買票只有一個人正在進行
去別人的伺服器抓資料
(1)通訊協定、機器名稱、port號三者都必須相同才符合同源政策
(2)
var cors = require("cors"); //引用cors物件
const corsOptions = {
origin: [ //把別人的伺服器放進來,跟人家要資料(別人可以拒絕
'http://www.beauty.com',
'http://localhost',
],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS'
};
methods:
Create → POST
Read → GET
Update → PUT
Delete → DELETE
function lab3(x, callback) {
x += 1;
callback(x);
}
lab3(20, function (value) {
//value = 10
alert(value);
console.log(value);
});
lab3(30, (value) => {
alert(value);
});
lab3(40, (value) => alert(value));
變數
var a =1;
參數
function lab(x) {
x += 1;
alert(x);
}
lab(10);